home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / a_utils / _archvrs / unix / shar.lha / shar / sysfuncs.c < prev    next >
C/C++ Source or Header  |  1987-12-03  |  5KB  |  264 lines

  1. /*
  2. **  System-specific stuff.  This module will need to be ported to
  3. **  other systems.
  4. */
  5. /* LINTLIBRARY */
  6. #include "shar.h"
  7. #include <signal.h>
  8. #include <pwd.h>
  9. #include <sys/stat.h>
  10. #ifdef    SYS_WAIT
  11. #include <sys/wait.h>
  12. #else
  13. #endif    /* SYS_WAIT */
  14. RCS("$Header: sysfuncs.c,v 1.7 87/03/13 13:08:34 rs Exp $")
  15.  
  16.  
  17. /* How to fork(), what to wait with. */
  18. #ifdef    SYS_WAIT
  19. #define FORK()         vfork()
  20. #define W_VAL(w)     ((w).w_retcode)
  21. typedef union wait     WAITER;
  22. #else
  23. #define FORK()         fork()
  24. #define W_VAL(w)     ((w) >> 8)
  25. typedef int         WAITER;
  26. #endif    /* SYS_WAIT */
  27.  
  28.  
  29. /* Mask of executable bits. */
  30. #define    EXE_MASK    (S_IEXEC | (S_IEXEC >> 3) | (S_IEXEC >> 6))
  31.  
  32. /* Stat buffer for last file. */
  33. static struct stat     Sb;
  34.  
  35.  
  36. /*
  37. **  Get user name.  Not secure, but who sends nastygrams as shell archives?
  38. */
  39. char *
  40. User()
  41. {
  42.     extern struct passwd    *getpwuid();
  43.     struct passwd        *p;
  44.     char            *g;
  45.  
  46.     if (g = getenv(USER_ENV))
  47.     return(g);
  48.     return((p = getpwuid(getuid())) ? p->pw_name : "USER");
  49. }
  50.  
  51.  
  52. /*
  53. **  Set up a signal handler.
  54. */
  55. SetSigs(What, Func)
  56.     int          What;
  57.     int        (*Func)();
  58. {
  59.     if (What == S_IGNORE)
  60.     Func = SIG_IGN;
  61.     else if (What == S_RESET)
  62.     Func = SIG_DFL;
  63.     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
  64.     (void)signal(SIGINT, Func);
  65.     if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
  66.     (void)signal(SIGQUIT, Func);
  67. }
  68.  
  69.  
  70. /*
  71. **  Stat the file if it's not the one we did last time.
  72. */
  73. int
  74. GetStat(p)
  75.     char        *p;
  76. {
  77.     static char         Name[BUFSIZ];
  78.  
  79.     if (*p == Name[0] && EQ(p, Name))
  80.     return(TRUE);
  81.     return(stat(strcpy(Name, p), &Sb) < 0 ? FALSE : TRUE);
  82. }
  83.  
  84.  
  85. /*
  86. **  Return the file type -- directory or regular file.
  87. */
  88. int
  89. Ftype(p)
  90.     char    *p;
  91. {
  92.     return(GetStat(p) && ((Sb.st_mode & S_IFMT) == S_IFDIR) ? F_DIR : F_FILE);
  93. }
  94.  
  95.  
  96. /*
  97. **  Return the file size.
  98. */
  99. off_t
  100. Fsize(p)
  101.     char    *p;
  102. {
  103.     return(GetStat(p) ? Sb.st_size : 0);
  104. }
  105.  
  106.  
  107. /*
  108. **  Is a file executable?
  109. */
  110. int
  111. Fexecute(p)
  112.     char    *p;
  113. {
  114.     return(GetStat(p) && (Sb.st_mode & EXE_MASK) ? TRUE : FALSE);
  115. }
  116.  
  117.  
  118. /*
  119. **  Return the process ID.
  120. */
  121. int
  122. Pid()
  123. {
  124.     static int     X;
  125.  
  126.     if (X == 0)
  127.     X = getpid();
  128.     return(X);
  129. }
  130.  
  131.  
  132. /*
  133. **  Return the text string that corresponds to errno.
  134. */
  135. char *
  136. Ermsg(e)
  137.     int             e;
  138. {
  139.     extern int         sys_nerr;
  140.     extern char        *sys_errlist[];
  141.     static char         buff[30];
  142.  
  143.     if (e > 0 && e < sys_nerr)
  144.     return(sys_errlist[e]);
  145.     (void)sprintf(buff, "Error code %d", e);
  146.     return(buff);
  147. }
  148.  
  149.  
  150. /*
  151. **  Fork off a command.
  152. */
  153. int
  154. Execute(av)
  155.     char        *av[];
  156. {
  157.     register int     i;
  158.     register int     j;
  159.     WAITER         W;
  160.  
  161.     if ((i = FORK()) == 0) {
  162.     SetSigs(S_RESET, (int (*)())NULL);
  163.     (void)execvp(av[0], av);
  164.     perror(av[0]);
  165.     _exit(1);
  166.     }
  167.  
  168.     SetSigs(S_IGNORE, (int (*)())NULL);
  169.     while ((j = wait(&W)) < 0 && j != i)
  170.     ;
  171.     SetSigs(S_RESET, (int (*)())NULL);
  172.     return(W_VAL(W));
  173. }
  174.  
  175.  
  176. #ifdef    NEED_MKDIR
  177. /*
  178. **  Quick and dirty mkdir routine for them that's need it.
  179. */
  180. int
  181. mkdir(name, mode)
  182.     char    *name;
  183.     int         mode;
  184. {
  185.     char    *av[3];
  186.     int         i;
  187.  
  188.     av[0] = "mkdir";
  189.     av[1] = name;
  190.     av[2] = NULL;
  191.     U = umask(~mode);
  192.     i = Execute(av);
  193.     (void)umask(U);
  194.     return(i ? -1 : 0);
  195. }
  196. #endif    /* NEED_MKDIR */
  197.  
  198.  
  199. #ifdef    NEED_QSORT
  200. /*
  201. **  Bubble sort an array of arbitrarily-sized elements.  This routine
  202. **  can be used as an (inefficient) replacement for the Unix qsort
  203. **  routine, hence the name.  If I were to put this into my C library,
  204. **  I'd do two things:
  205. **    -Make it be a quicksort;
  206. **    -Have a front routine which called specialized routines for
  207. **     cases where Width equals sizeof(int), sizeof(char *), etc.
  208. */
  209. qsort(Table, Number, Width, Compare)
  210.     register char     *Table;
  211.     register int      Number;
  212.     register int      Width;
  213.     register int    (*Compare)();
  214. {
  215.     register char     *i;
  216.     register char     *j;
  217.  
  218.     for (i = &Table[Number * Width]; (i -= Width) >= &Table[Width]; )
  219.     for (j = i; (j -= Width) >= &Table[0]; )
  220.         if ((*Compare)(i, j) < 0) {
  221.         register char    *p;
  222.         register char    *q;
  223.         register int     t;
  224.         register int     w;
  225.  
  226.         /* Swap elements pointed to by i and j. */
  227.         for (w = Width, p = i, q = j; --w >= 0; *p++ = *q, *q++ = t)
  228.             t = *p;
  229.         }
  230. }
  231. #endif    /* NEED_QSORT */
  232.  
  233.  
  234. #undef NOTDEF
  235. #ifdef    NOTDEF
  236. /*
  237. **  Cons all the arguments together into a single command line and hand
  238. **  it off to the shell to execute.  This is only here for someone to use
  239. **  as the basis of, say, an MSDOS port.
  240. */
  241. int
  242. Execute(av)
  243.     register char    *av[];
  244. {
  245.     register char    **v;
  246.     register char     *p;
  247.     register char     *q;
  248.     register int     i;
  249.  
  250.     /* Get length of command line. */
  251.     for (i = 5, v = av; *v; v++)
  252.     i += strlen(*v) + 1;
  253.  
  254.     /* Create command line and execute it. */
  255.     p = NEW(char, i);
  256.     for (q = p + strlen(strcpy(p, "exec")), v = av; *v; v++) {
  257.     *q++ = ' ';
  258.     q += strlen(strcpy(q, *v));
  259.     }
  260.  
  261.     return(system(p));
  262. }
  263. #endif    /* NOTDEF */
  264.